package com.team2.shoppingService;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import com.team2.shared.*;


public class Server implements CyberServer{
	protected String baseUrl = "http://54.225.220.149:8080/CyberServer";
	protected String productServlet = "/productservlet";
	protected String storeServlet = "/storeservlet";
	protected String barcodeServlet = "/barcodeservlet";
	
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
//		 try {
//			Server server = new Server();
//			server.setBaseUrl("http://localhost:8080/CyberServer");
//			ArrayList<Product> products=server.searchProducts("fridge");
//			System.out.println(products);
//		} catch (CyberException e) {
//			// TODO Auto-generated catch block
//			e.printStackTrace();
//		}
		
		
		
	}

	@SuppressWarnings("unchecked")
	@Override
	public ArrayList<Product> searchProducts(String tags) throws CyberException{
		ArrayList<ServerProduct> serverProducts = null;
		String url = baseUrl+productServlet+"?tags="+tags;
		url +="&token="+Util.computeHashFromBytes(SharedConstants.TOKEN.getBytes());
		System.out.println(url);
		try {
			HttpURLConnection httpConnection = (HttpURLConnection) new URL(url).openConnection();
			httpConnection.setRequestMethod("GET");
			int statusCode = httpConnection.getResponseCode();
			
			if (statusCode == 200) {
				InputStream content = httpConnection.getInputStream();
				ObjectInputStream in = new ObjectInputStream(content);
				serverProducts = (ArrayList<ServerProduct>) in.readObject();
			} else {
				
				throw new CyberException("Internal Server Error: "+statusCode);
			}
		}  catch (IOException e) {
			throw new CyberException("Internet connection problem");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		return Product.fromServerProducts(serverProducts);
	}

	@Override
	public ArrayList<Store> searchStores(Product product, double latitude, double longitude, int radius) {
		// TODO Auto-generated method stub
		ArrayList<Store> stores =new ArrayList<Store>();
		
		for(Store store: product.getStores()){
			StoreRequest request = new StoreRequest(store.getBrand(), store.getPrice());
			if(latitude != 0 &&
			   longitude !=0 &&
			   radius !=0){
			request.setLatitude(latitude);
			request.setLongitude(longitude);
			request.setRadius(radius);
			}
			stores.addAll(request.execute());
		}
		return stores;
	}

	public void setBaseUrl(String baseUrl) {
		this.baseUrl = baseUrl;
	}


	@SuppressWarnings("unchecked")
	@Override
	public ArrayList<Product> searchProducts(String tags, String filePath,
			String category, boolean isUseImageMatch) throws CyberException {
		// TODO Auto-generated method stub
		ArrayList<ServerProduct> products=null;
		String url = baseUrl+productServlet+"?tags="+tags;
		url += "&category="+category;
		url +="&token="+Util.computeHashFromBytes(SharedConstants.TOKEN.getBytes());
		if(isUseImageMatch){
			url += "&"+SharedConstants.isImageMatch+"="+SharedConstants.TRUE;
		}
		System.out.println(url);
		try {
			HttpURLConnection httpConnection = (HttpURLConnection) new URL(url).openConnection();
			httpConnection.setDoOutput(true);
			OutputStream os = httpConnection.getOutputStream();
			FileInputStream fis = new FileInputStream(filePath);
			byte[] buffer = new byte[8000];
			int numberRead = fis.read(buffer);
			while(numberRead >0){
				os.write(buffer, 0, numberRead);
				numberRead = fis.read(buffer);
			}
			fis.close();
			//httpConnection.setRequestMethod("GET");
			int statusCode = httpConnection.getResponseCode();
			
			if (statusCode == 200) {
				InputStream content = httpConnection.getInputStream();
				ObjectInputStream in = new ObjectInputStream(content);
				products = (ArrayList<ServerProduct>) in.readObject();
			} else {
				
				throw new CyberException("Internal Server Error: "+statusCode);
			}
		}  catch (IOException e) {
			e.printStackTrace();
			throw new CyberException("Internet connection problem");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		return Product.fromServerProducts(products);
	}

	@SuppressWarnings("unchecked")
	public ArrayList<Product> searchProductsWithCategory(String tags, String category) throws CyberException {
		ArrayList<ServerProduct> serverProducts = null;
		String url = baseUrl+productServlet+"?tags="+tags;
		url += "&category="+category;
		url +="&token="+Util.computeHashFromBytes(SharedConstants.TOKEN.getBytes());
		System.out.println(url);
		try {
			HttpURLConnection httpConnection = (HttpURLConnection) new URL(url).openConnection();
			httpConnection.setRequestMethod("GET");
			int statusCode = httpConnection.getResponseCode();
			
			if (statusCode == 200) {
				InputStream content = httpConnection.getInputStream();
				ObjectInputStream in = new ObjectInputStream(content);
				serverProducts = (ArrayList<ServerProduct>) in.readObject();
			} else {
				
				throw new CyberException("Internal Server Error: "+statusCode);
			}
		}  catch (IOException e) {
			throw new CyberException("Internet connection problem");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		return Product.fromServerProducts(serverProducts);
	}
	@Override
	public String recognizeBarcode(String barcode) throws CyberException{
		// TODO Auto-generated method stub
		String title=null;
		String url = baseUrl+barcodeServlet+"?"+SharedConstants.BARCODE+"="+barcode;
		url +="&token="+Util.computeHashFromBytes(SharedConstants.TOKEN.getBytes());
		System.out.println(url);
		
		try {
			HttpURLConnection httpConnection = (HttpURLConnection) new URL(url).openConnection();
			httpConnection.setRequestMethod("GET");
			int statusCode = httpConnection.getResponseCode();
			
			if (statusCode == 200) {
				InputStream content = httpConnection.getInputStream();
				BufferedReader br = new BufferedReader(new InputStreamReader(content));
				title = br.readLine();
			} else {	
				InputStream content = httpConnection.getInputStream();
				BufferedReader br = new BufferedReader(new InputStreamReader(content));
				title = br.readLine();
				throw new CyberException(title);
			}
		} catch (IOException e) {
			throw new CyberException("Internet connection problem");
		}
		
		return title;
	}
	
	public ArrayList<Product> searchOnlineProducts(String tags, String category){
		GoogleShoppingRequest request = new GoogleShoppingRequest(tags);
		request.setRankbyPrice();
		return request.execute();
	}

	@Override
	public ArrayList<Product> searchOnlineProducts (String tags,
			String category, String filePath) throws CyberException{
		// TODO Auto-generated method stub
		// TODO Auto-generated method stub
				ArrayList<ServerProduct> products=null;
				String url = baseUrl+productServlet+"?tags="+tags;
				url += "&category="+category;
				url += "&"+SharedConstants.isImageMatch+"="+SharedConstants.TRUE;
				url += "&isOnline="+SharedConstants.TRUE;
				url +="&token="+Util.computeHashFromBytes(SharedConstants.TOKEN.getBytes());
				System.out.println(url);
				try {
					HttpURLConnection httpConnection = (HttpURLConnection) new URL(url).openConnection();
					httpConnection.setDoOutput(true);
					OutputStream os = httpConnection.getOutputStream();
					FileInputStream fis = new FileInputStream(filePath);
					byte[] buffer = new byte[8000];
					int numberRead = fis.read(buffer);
					while(numberRead >0){
						os.write(buffer, 0, numberRead);
						numberRead = fis.read(buffer);
					}
					fis.close();
					//httpConnection.setRequestMethod("GET");
					int statusCode = httpConnection.getResponseCode();
					
					if (statusCode == 200) {
						InputStream content = httpConnection.getInputStream();
						ObjectInputStream in = new ObjectInputStream(content);
						products = (ArrayList<ServerProduct>) in.readObject();
					} else {
						
						throw new CyberException("Internal Server Error: "+statusCode);
					}
				}  catch (IOException e) {
					e.printStackTrace();
					throw new CyberException("Internet connection problem");
				} catch (ClassNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} 
				return Product.fromServerProducts(products);
	}

}
